﻿/*******************************************************************************
 * 文件名称: AutoClearFolder.AppConfig
 * 文件描述: 
 * 创 建 者: chenbq
 * 创建时间: 2020-6-23 17:06:02
 * 修 改 者: 
 * 修改时间：
 * 备    注：
 * ------------------------------------------------------------------------------
 * Copyright (C) 2017-2020 厦门拜特信息科技有限公司
*********************************************************************************/
using System;
using System.IO;
using System.Xml;

namespace AutoClearFolder
{
    /// <summary>
    /// 用于获取或设置Web.config/*.exe.config中节点数据的辅助类
    /// </summary>
    public sealed class AppConfig
    {
        private string _FilePath = string.Empty;

        #region 构造函数

        /// <summary>
        /// 从当前目录中按顺序检索Web.Config和*.App.Config文件。
        /// 如果找到一个，则使用它作为配置文件；否则会抛出一个ArgumentNullException异常。
        /// </summary>
        public AppConfig()
        {
            string webconfig = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web.Config");
            string appConfig = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile.Replace(".vshost", "");

            if (File.Exists(webconfig))
            {
                _FilePath = webconfig;
            }
            else if (File.Exists(appConfig))
            {
                _FilePath = appConfig;
            }
            else
            {
                throw new ArgumentNullException("没有找到Web.Config文件或者应用程序配置文件, 请指定配置文件");
            }
        }

        /// <summary>
        /// 用户指定具体的配置文件路径
        /// </summary>
        /// <param name="configFilePath">配置文件路径（绝对路径）</param>
        public AppConfig(string configFilePath)
        {
            _FilePath = configFilePath;
        }

        #endregion

        /// <summary>
        /// 设置程序的config文件
        /// </summary>
        /// <param name="keyName">键名</param>
        /// <param name="keyValue">键值</param>
        public void AppConfigSet(string keyName, string keyValue)
        {
            //由于存在多个Add键值，使得访问appSetting的操作不成功，故注释下面语句，改用新的方式
            /* 
            string xpath = "//add[@key='" + keyName + "']";
            XmlDocument document = new XmlDocument();
            document.Load(filePath);

            XmlNode node = document.SelectSingleNode(xpath);
            node.Attributes["value"].Value = keyValue;
            document.Save(filePath); 
             */

            XmlDocument document = new XmlDocument();
            document.Load(_FilePath);

            XmlNodeList nodes = document.GetElementsByTagName("add");

            var existFlag = false;

            for (int i = 0; i < nodes.Count; i++)
            {
                //获得将当前元素的key属性
                XmlAttribute attribute = nodes[i].Attributes["key"];
                //根据元素的第一个属性来判断当前的元素是不是目标元素
                if (attribute != null && (attribute.Value == keyName))
                {
                    attribute = nodes[i].Attributes["value"];
                    //对目标元素中的第二个属性赋值
                    if (attribute != null)
                    {
                        existFlag = true;
                        attribute.Value = keyValue;
                        break;
                    }
                }
            }

            //找不到节点则添加新节点。
            if (existFlag == false)
            {
                XmlElement newEle = document.CreateElement("add");
                XmlAttribute newKey = document.CreateAttribute("key");
                newKey.Value = keyName;
                XmlAttribute newValue = document.CreateAttribute("value");
                newValue.Value = keyValue;

                newEle.Attributes.Append(newKey);
                newEle.Attributes.Append(newValue);

                var settingNode = document.SelectSingleNode("/configuration/appSettings");
                settingNode.AppendChild(newEle);
            }

            document.Save(_FilePath);
        }

        /// <summary>
        /// 读取程序的config文件的键值。
        /// 如果键名不存在，返回空
        /// </summary>
        /// <param name="keyName">键名</param>
        /// <returns></returns>
        public string GetValue(string keyName)
        {
            string strReturn = string.Empty;
            try
            {
                XmlDocument document = new XmlDocument();
                document.Load(_FilePath);

                XmlNodeList nodes = document.GetElementsByTagName("add");
                for (int i = 0; i < nodes.Count; i++)
                {
                    //获得将当前元素的key属性
                    XmlAttribute attribute = nodes[i].Attributes["key"];
                    //根据元素的第一个属性来判断当前的元素是不是目标元素
                    if (attribute != null && (attribute.Value == keyName))
                    {
                        attribute = nodes[i].Attributes["value"];
                        if (attribute != null)
                        {
                            strReturn = attribute.Value;
                            break;
                        }
                    }
                }
            }
            catch
            {
                ;
            }

            return strReturn;
        }

        /// <summary>
        /// 获取指定键名中的子项的值
        /// </summary>
        /// <param name="keyName">键名</param>
        /// <param name="subKeyName">以分号(;)为分隔符的子项名称</param>
        /// <returns>对应子项名称的值（即是=号后面的值）</returns>
        public string GetSubValue(string keyName, string subKeyName)
        {
            string connectionString = GetValue(keyName).ToLower();
            string[] item = connectionString.Split(new char[] { ';' });

            for (int i = 0; i < item.Length; i++)
            {
                string itemValue = item[i].ToLower();
                if (itemValue.IndexOf(subKeyName.ToLower()) >= 0) //如果含有指定的关键字
                {
                    int startIndex = item[i].IndexOf("="); //等号开始的位置
                    return item[i].Substring(startIndex + 1); //获取等号后面的值即为Value
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 静态实例
        /// </summary>
        public static AppConfig Instance
        {
            get { return new AppConfig(); }
        }

    }
}
